package com.kkb.controller.file;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.kkb.bean.FileTable;
import com.kkb.bean.TagsTable;
import com.kkb.service.file.FileTableService;
import com.kkb.service.file.FileTagsTableService;
import com.kkb.service.file.TagsTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;

/**
 * @Author 何世鹏
 * @Date 2021/4/12 15:41
 */
@RestController
public class FileTableController {
    @Autowired
    private FileTableService fileTableService;

    @Autowired
    private TagsTableService tagsTableService;

    @Autowired
    private FileTagsTableService fileTagsTableService;

    /**
     * 查询文档信息
     *
     * @param req   请求
     * @param resp  响应
     * @param state 0：审核中  1：已上架  2：未通过
     * @param type  0:共享文档  1:付费文档  2:VIP专享文档
     * @return json格式
     */
    @GetMapping("/get/file/list")
    public String getList(HttpServletRequest req, HttpServletResponse resp, Integer state, Integer type) {
        String list = fileTableService.getList(req, resp, state, type);
        return list;
    }

    /**
     * 文档上传
     *
     * @param req       请求
     * @param resp      响应
     * @param file1     文档
     * @param file2     封面
     * @param fileTable 文档信息
     * @return 添加成功/失败
     */
    @PostMapping("/upLoad/file")
    public String upLoad(HttpServletRequest req, HttpServletResponse resp, @RequestParam("file1") MultipartFile file1, @RequestParam("file2") MultipartFile file2, FileTable fileTable) {
        //原始名称-文档
        String originalFilename1 = file1.getOriginalFilename();
        fileTable.setFileName(originalFilename1);
        //原始名称-封面
        String originalFilename2 = file2.getOriginalFilename();
        //文件新名字
        String fileName1 = UUID.randomUUID().toString().replace("-", "") + originalFilename1.substring(originalFilename1.lastIndexOf("."));
        System.out.println("文件名称：" + fileName1);
        //文件新名字
        String fileName2 = UUID.randomUUID().toString().replace("-", "") + originalFilename2.substring(originalFilename2.lastIndexOf("."));
        System.out.println("文件名称：" + fileName2);
        //存储位置
        String realPath = req.getServletContext().getRealPath("/upload/file") + "/";
        System.out.println("路径：" + realPath);
        try {
            file1.transferTo(new File(realPath + fileName1));
            file2.transferTo(new File(realPath + fileName2));
            String path1 = fileName1;
            String path2 = fileName2;
            fileTable.setFilePath(path1);
            fileTable.setFileCoverPath(path2);
            System.out.println("上传成功:" + path1);
            System.out.println("上传成功:" + path2);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("上传失败~");
            return "上传失败~";
        }
        //添加标签
        List<TagsTable> tags = fileTable.getTags();
        if (tags != null) {
            for (TagsTable tag : tags) {
                tagsTableService.addTags(req, resp, tag);
            }
        }
        //添加文件
        Boolean aBoolean = fileTableService.addList(req, resp, fileTable);
        return aBoolean ? "添加成功" : "添加失败";
    }

    /**
     * 下载
     *
     * @param req    请求
     * @param resp   响应
     * @param fileId 文件id
     * @return 下载文件流
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/download/file/id")
    public ResponseEntity<byte[]> download(HttpServletRequest req, HttpServletResponse resp, Integer fileId) throws UnsupportedEncodingException {
        String filePath = fileTableService.getFilePath(req, resp, fileId);
        if (filePath != null) {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            httpHeaders.setContentDispositionFormData("attachment", URLEncoder.encode(filePath, "UTF-8"));
            String realPath = req.getServletContext().getRealPath("/upload/file") + "/";
            File file = new File(realPath + filePath);
            ResponseEntity<byte[]> r = new ResponseEntity<>(FileUtil.readBytes(file), httpHeaders, HttpStatus.CREATED);
            return r;
        } else {
            return null;
        }
    }

    /**
     * 默认逻辑删除，如文集包含删除的文档，则删除中间表中的文档信息
     * 存在的问题：文集删除文档后，包含文档数小于3
     * 解决方案1：逻辑删除文档，但不删除文集对应关系，用户依然可以通过文集下载已删除的文档，但是无法加入到新的文集中。
     * 解决方案2：当删除文档后，所关联的文集如文档数小于3，则删除文集。
     * 本接口采用->解决方案1
     *
     * @param req 请求
     * @param resp 响应
     * @param id 文档ID
     * @return 删除成功
     */
    @DeleteMapping("/del/file/id")
    public String del(HttpServletRequest req, HttpServletResponse resp, Integer id) {
        fileTableService.delFile(req, resp, id);
        return "删除成功！";
    }

    /**
     *
     * @param req 请求
     * @param resp 响应
     * @param fileId 文档ID
     * @return 文档实体类
     */
    @GetMapping("/select/file/id")
    public String selectById(HttpServletRequest req, HttpServletResponse resp,Integer fileId) {
        FileTable fileTable = fileTableService.selectById(req,resp,fileId);
        return JSON.toJSONString(fileTable);
    }

    /**
     * 文档修改
     *
     * @param req       请求
     * @param resp      响应
     * @param file1     文档
     * @param file2     封面
     * @param fileTable 文档信息
     * @return 上传成功/失败
     */
    @PostMapping("/update/file")
    public String update(HttpServletRequest req, HttpServletResponse resp, @RequestParam("file1") MultipartFile file1, @RequestParam("file2") MultipartFile file2, FileTable fileTable) {
        //存储位置
        String realPath = req.getServletContext().getRealPath("/upload/file") + "/";
        System.out.println("路径：" + realPath);
        //原始名称-文档,前端去看是否和原来文集一致，一直则不传到后台
        if (file1 != null){
            //新上传了文档
            String originalFilename1 = file1.getOriginalFilename();
            fileTable.setFileName(originalFilename1);
            //文件新名字
            String fileName1 = UUID.randomUUID().toString().replace("-", "") + originalFilename1.substring(originalFilename1.lastIndexOf("."));
            System.out.println("文件名称：" + fileName1);
            try {
                file1.transferTo(new File(realPath + fileName1));
                String path1 = fileName1;
                fileTable.setFilePath(path1);
                System.out.println("上传成功:" + path1);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("上传失败~");
                return "上传失败~";
            }
        }
        if (file2 != null){
            //新上传了封面
            //原始名称-封面
            String originalFilename2 = file2.getOriginalFilename();
            //文件新名字
            String fileName2 = UUID.randomUUID().toString().replace("-", "") + originalFilename2.substring(originalFilename2.lastIndexOf("."));
            System.out.println("文件名称：" + fileName2);
            try {
                file2.transferTo(new File(realPath + fileName2));
                String path2 = fileName2;
                fileTable.setFileCoverPath(path2);
                System.out.println("上传成功:" + path2);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("上传失败~");
                return "上传失败~";
            }
        }
        //添加标签
        List<TagsTable> tags = fileTable.getTags();
        if (tags != null) {
            //更新标签
            //1.先去中间表把存在的标签关系删除
            fileTagsTableService.del(req,resp,fileTable.getFileId());
            //2.重新建立联系
            for (TagsTable tag : tags) {
                tagsTableService.addTags(req, resp, tag);
            }
        }
        //添加文件
        Boolean aBoolean = fileTableService.updateFile(req, resp, fileTable);
        return aBoolean ? "修改成功" : "修改失败";
    }


}
